import { Console } from 'console';
import * as fs from 'fs';
import * as path from 'path';

/**
 * @en Registration method for the main process of Extension
 * @zh 为扩展的主进程的注册方法
 */
export const methods: { [key: string]: (...any: any) => any } = {
	MapPath(){
		console.log('MapPath Start');
		mapImportJson();
		mapTSConfig();
		console.log('MapPath Finish');
	},
};

/**
 * @en Hooks triggered after extension loading is complete
 * @zh 扩展加载完成后触发的钩子
 */
export function load() { }

/**
 * @en Hooks triggered after extension uninstallation is complete
 * @zh 扩展卸载完成后触发的钩子
 */
export function unload() { }

//获取工程目录
function getDir(){
	const dir = path.resolve(__dirname, '../../..');
	return dir;
}

function getConfigPath(){
	const configPath = path.resolve(__dirname, 'config.txt');
	return configPath;
}

let windowSlash = "\\";
let linuxSlash = "/";

//把路径的\全部替换为/
function getLinuxPath(fullPath: string) :string{
	let fullPaths = fullPath.split(windowSlash);
	if(fullPaths.length < 2)
		return fullPath;
	fullPath = fullPaths[0];
	for (let index = 1; index < fullPaths.length; index++) {
		fullPath += "/" + fullPaths[index];
	}
	return fullPath;
}

//获取文件名（不包含文件后缀）
function getFileNameWithoutExtend(fullPath: string) :string{
	var lastIndexSlash = fullPath.lastIndexOf(linuxSlash);
	var lastIndexDot = fullPath.lastIndexOf('.');
	let res = fullPath.substring(lastIndexSlash + 1, lastIndexDot);  
	return res;
}

//获取路径（不包含文件后缀）
function getPathWihtouExtend(fullPath: string) :string{
	var lastIndexDot = fullPath.lastIndexOf('.');
	let res = fullPath.substring(0, lastIndexDot);  
	return res;
}

let filesTS: string[];
/**
 * 文件遍历方法
 * @param filePath 需要遍历的文件路径
 */
function fileSearch(filePath: string) {
  	// 根据文件路径读取文件，返回一个文件列表
  	let files = fs.readdirSync(filePath);
    if (files.length == 0 ) {
      console.warn(" Can not find:" + filePath);
      return;
    }
	
    // 遍历读取到的文件列表
    files.forEach(filename => {
      	// path.join得到当前文件的绝对路径
      	const filepath = path.join(filePath, filename);
      	// 根据文件路径获取文件信息
     	let stats = fs.statSync(filepath);

        const isFile = stats.isFile(); // 是否为文件
        const isDir = stats.isDirectory(); // 是否为文件夹
        if (isFile) {
		  if(!filepath.endsWith(".meta")){
			filesTS.push(filepath);
		  }
        }
        if (isDir) {
          fileSearch(filepath); // 递归，如果是文件夹，就继续遍历该文件夹里面的文件；
        }
  	});
}

//获取需要映射的文件
function getFiles2Map(): string[][] {
	filesTS = [];//全局变量

	//枚举脚本路径
	let configPath = getConfigPath();
	var fileContent = fs.readFileSync(configPath, "utf-8");
	var scriptsFiles: string[] = fileContent.split(',');
	scriptsFiles.forEach(scriptFile => {
		const scriptDir = getDir() + "/assets/" + scriptFile;
		//console.log("scriptFile:" + scriptFile + " scriptDir:" + scriptDir);
		if(!fs.existsSync(scriptDir)){
			console.error("Can not find dir:" + scriptDir);
		}else{
			fileSearch(scriptDir);
		}
	});

	let rootDir = getDir();
	rootDir = getLinuxPath(rootDir);
	let fileNameWithoutExtends : string[] = [];
	let fileNameFulls : string[] = [];
	for (let index = 0; index < filesTS.length; index++) {
		const file = filesTS[index];
		let fileChange = getLinuxPath(file);
		fileNameWithoutExtends.push(getFileNameWithoutExtend(fileChange)); 
		fileNameFulls.push(fileChange.replace(rootDir, "."));
	}
	let ret = [fileNameWithoutExtends, fileNameFulls];
	return ret;
}

function mapImportJson(){
	const importMapPath = getDir() + '/import-map.json';

	let exist = fs.existsSync(importMapPath);
	if(!exist){
		console.log("Can not find importMapPath:" + importMapPath);
	}

	let files2Save = getFiles2Map();
	let fileNameWithoutExtends : string[] = files2Save[0];
	let fileNameFulls : string[] = files2Save[1];
	let endTag;
	let fileContent = '{\n "imports": {';
	for (let index = 0; index < filesTS.length; index++) {
		if(index == filesTS.length -1)
			endTag = "";
		else
			endTag = ",";
		fileContent += "\n  \"" + fileNameWithoutExtends[index] + "\": \"" + fileNameFulls[index] + "\"" + endTag;
	}
	fileContent += "\n }";
	fileContent += "\n}";
	fs.writeFileSync(importMapPath, fileContent);
}

function mapTSConfig(){
	const tsconfigPath = getDir() + '/tsconfig.json';

	let exist = fs.existsSync(tsconfigPath);
	if(!exist){
		console.error("无法找到tsconfig.json:" + tsconfigPath)
		return;
	}
	let readf = fs.readFileSync(tsconfigPath, "utf8")

	//let isMatch = readf.match("/\"paths\"\: \{[\s\S]*?\}/gm");
	let splitTag = "\r\n";
	let contentArray = readf.split(splitTag);
	if(contentArray.length < 2){
		splitTag = "\r";
		contentArray = readf.split(splitTag);
		if(contentArray.length < 2){
			console.error("tsconfig 读取文件错误");
			return;
		}
	}
	let fileContent = "";
	let isReplace = false;
	let isFindPathsTag = false;
	for (let index = 0; index < contentArray.length; index++) {
		const content = contentArray[index];
		if(content.indexOf("\"paths\":") >= 0){
			isReplace = true;
			isFindPathsTag = true;
			fileContent = mapTSConfigPaths(fileContent, splitTag);
		}

		if(isReplace){
			if(content.indexOf("}") >= 0)
				isReplace = false;
		}

		if(!isReplace){
			if(index == contentArray.length - 1)
				fileContent += content;
			else
				fileContent += content + splitTag;
		}
	};

	if(!isFindPathsTag){
		console.error("Fatal Error:Can not find paths elem at ->" + tsconfigPath);
		console.error("Before exe this cmd, please insert the below content to \"compilerOptions\": { at ->" + tsconfigPath + splitTag +
			"\"paths\": {" + splitTag + "}"
		);
		return;
	}
	fs.writeFileSync(tsconfigPath, fileContent);
}

function mapTSConfigPaths(fileContent: string, splitTag: string) : string{
	let files2Save = getFiles2Map();
	let fileNameWithoutExtends : string[] = files2Save[0];
	let fileNameFulls : string[] = files2Save[1];
	let endTag;
	fileContent += '    "paths": {' + splitTag;
	for (let index = 0; index < filesTS.length; index++) {
		if(index == filesTS.length -1)
			endTag = "";
		else
			endTag = ",";
		fileContent += "      \"" + fileNameWithoutExtends[index] + "\": [\"" + getPathWihtouExtend(fileNameFulls[index]) + "\"]" + endTag + splitTag;
	}
	return fileContent;
}